package com.taotao.job.trigger;

import com.google.common.base.Preconditions;
import com.taotao.job.core.model.JobMeta;
import com.taotao.job.core.trigger.Trigger;
import com.taotao.job.core.trigger.TriggerResult;
import com.taotao.job.core.trigger.context.TriggerContext;
import com.taotao.job.core.trigger.context.TriggerFeature;
import com.taotao.job.core.util.JobBussinessUtil;
import com.taotao.job.model.entity.JobTriggerMeta;
import com.taotao.job.service.JobRunInstanceService;
import com.taotao.job.service.JobTriggerMetaService;

import java.util.List;


/**
 * @author fanbeibei
 * @version 1.0
 * @date 2021/2/4 15:00
 */
public abstract class AbstractTrigger implements Trigger {

    private JobRunInstanceService runInstanceService;

    private JobTriggerMetaService triggerMetaService;


    @Override
    public TriggerResult trigger(JobMeta jobMeta, TriggerFeature triggerFeature, long shouldTriggerTime) {

        Preconditions.checkArgument(null != jobMeta);
        Preconditions.checkArgument(null != triggerFeature);


        JobTriggerMeta triggerMeta = triggerMetaService.queryById(jobMeta.getJobId());
        if (null == triggerMeta) {
            throw new IllegalStateException("can not get JobTriggerMeta by jobId " + jobMeta.getJobId());
        }


        if (triggerMeta.getShardingCount() > 1) {


            //分片任务
            for (int i = 0; i < triggerMeta.getShardingCount(); i++) {

                Long mainRunInstanceId = runInstanceService.createShardingMainRunInstance(jobMeta, triggerFeature, triggerMeta);
                TriggerContext tc = createTriggerContext(jobMeta, triggerFeature, triggerMeta, i, shouldTriggerTime);
                triggerSharding(tc, getExecutorAdressList(), mainRunInstanceId);
                return TriggerResult.builder().code(TriggerResult.RESULT_SUCCESS).runInstanceId(mainRunInstanceId).build();
            }
        } else {
            Long runInstanceId = runInstanceService.createRunInstance(jobMeta, triggerFeature, triggerMeta);
            TriggerContext tc = createTriggerContext(jobMeta, triggerFeature, triggerMeta, 0, shouldTriggerTime);
            trigger0(tc, getExecutorAdressList());

            return TriggerResult.builder().code(TriggerResult.RESULT_SUCCESS).runInstanceId(runInstanceId).build();

        }


        return null;
    }


    @Override
    public TriggerResult manualTrigger(Long jobId, String executorParam, boolean runPost) {
        return null;
    }


    protected void triggerSharding(TriggerContext tc, List<String> executorAdressList, Long mainRunInstanceId) {

    }

    protected void trigger0(TriggerContext tc, List<String> executorAdressList) {

    }

    /**
     * 创建触发上下文
     *
     * @param jobMeta
     * @param triggerFeature
     * @param triggerMeta
     * @param shardingIndex
     * @param shouldTriggerTime
     * @return
     */
    public static TriggerContext createTriggerContext(JobMeta jobMeta, TriggerFeature triggerFeature, JobTriggerMeta triggerMeta, int shardingIndex, long shouldTriggerTime) {
        return TriggerContext.builder().jobMeta(jobMeta).triggerFeature(triggerFeature)
                .shardingCount(triggerMeta.getShardingCount()).shardingIndex(shardingIndex)
                .shouldTriggerTime(shouldTriggerTime).triggerTime(System.currentTimeMillis())
                .executorRouteStrategy(triggerMeta.getExecutorRouteStrategy()).build();
    }


    /**
     * 获取执行器地址
     *
     * @return
     */
    protected abstract List<String> getExecutorAdressList();

}
